home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 25 / CU Amiga Magazine's Super CD-ROM 25 (1998)(EMAP Images)(GB)(Track 1 of 2)[!][issue 1998-08].iso / CUCD / Programming / QuakeTools / src / libqdisplay / surface.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-06-12  |  9.9 KB  |  273 lines

  1. #define    LIBQDISPLAY_CORE
  2. #define    LIBQTOOLS_CORE
  3. #define    LIBQBUILD_CORE
  4. #include "../include/libqdisplay.h"
  5.  
  6. /*
  7.  * lightmap related
  8.  */
  9. static int row, lightmapWidth, step, shift;
  10. static int *lightmapIndex;
  11.  
  12. static void BuildLightBlock(unsigned char *out, struct bitmap *raw, int x, int y)
  13. {
  14.   int c, dc;
  15.   int a, b, h, c0, c1, c2, c3;
  16.   int y_max = raw->height, x_max = raw->width;
  17.   unsigned char *fullbright = raw->data + lookup(y, raw->width);
  18.  
  19.   c0 = ((255 << 6) - lightmapIndex[0]);
  20.   c1 = ((255 << 6) - lightmapIndex[1]);
  21.   c2 = ((255 << 6) - lightmapIndex[lightmapWidth]);
  22.   c3 = ((255 << 6) - lightmapIndex[lightmapWidth + 1]);
  23.  
  24.   c2 = (c2 - c0) >> shift;
  25.   c3 = (c3 - c1) >> shift;
  26.  
  27.   for (b = 0; b < step; ++b) {
  28.     h = x;
  29.     c = c0;
  30.     dc = (c1 - c0) >> shift;
  31.     for (a = 0; a < step; ++a) {
  32.       unsigned char pel = fullbright[h];
  33.       *out++ = cachedColormap[(c & 0x00003F00) + pel];
  34.       c += dc;
  35.       if (++h == x_max)
  36.     h = 0;
  37.     }
  38.     out += row;
  39.     c0 += c2;
  40.     c1 += c3;
  41.     if (++y == y_max) {
  42.       y = 0;
  43.       fullbright = raw->data;
  44.     }
  45.     else
  46.       fullbright += raw->width;
  47.   }
  48. }
  49.  
  50. static unsigned char *brightColormap;
  51. static void BuildBrightBlock(unsigned char *out, struct bitmap * raw, int x, int y)
  52. {
  53.   int a, b, h;
  54.   int y_max = raw->height, x_max = raw->width;
  55.   unsigned char *fullbright = raw->data + lookup(y, raw->width);
  56.  
  57.   for (b = 0; b < step; ++b) {
  58.     h = x;
  59.     for (a = 0; a < step; ++a) {
  60.       unsigned char pel = fullbright[h];
  61.       *out++ = brightColormap[pel];
  62.       if (++h == x_max)
  63.     h = 0;
  64.     }
  65.     out += row;
  66.     if (++y == y_max) {
  67.       y = 0;
  68.       fullbright = raw->data;
  69.     }
  70.     else
  71.       fullbright += raw->width;
  72.   }
  73. }
  74.  
  75. short int lightstyleStrings[16][64] = {
  76.   // 0 normal
  77.   // "m",
  78.   {12*22>>2},
  79.   // 1 FLICKER (first variety)
  80.   // "mmnmmommommnonmmonqnmmo",
  81.   {12*22>>2,12*22>>2,13*22>>2,12*22>>2,12*22>>2,14*22>>2,12*22>>2,12*22>>2,14*22>>2,12*22>>2,12*22>>2,13*22>>2,14*22>>2,
  82.    13*22>>2,12*22>>2,12*22>>2,14*22>>2,13*22>>2,16*22>>2,13*22>>2,12*22>>2,12*22>>2,14*22>>2},
  83.   // 2 SLOW STRONG PULSE
  84.   // "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba",
  85.   {0*22>>2,1*22>>2,2*22>>2,3*22>>2,4*22>>2,5*22>>2,6*22>>2,7*22>>2,8*22>>2,9*22>>2,10*22>>2,11*22>>2,12*22>>2,13*22>>2,14*22>>2,
  86.    15*22>>2,16*22>>2,17*22>>2,18*22>>2,19*22>>2,20*22>>2,21*22>>2,22*22>>2,23*22>>2,24*22>>2,25*22>>2,24*22>>2,23*22>>2,
  87.    22*22>>2,21*22>>2,20*22>>2,19*22>>2,18*22>>2,17*22>>2,16*22>>2,15*22>>2,14*22>>2,13*22>>2,12*22>>2,11*22>>2,10*22>>2,
  88.    9*22>>2,8*22>>2,7*22>>2,6*22>>2,5*22>>2,4*22>>2,3*22>>2,2*22>>2,1*22>>2,0*22>>2},
  89.   // 3 CANDLE (first variety)
  90.   // "mmmmmaaaaammmmmaaaaaabcdefgabcdefg",
  91.   {12*22>>2,12*22>>2,12*22>>2,12*22>>2,12*22>>2,00*22>>2,00*22>>2,00*22>>2,00*22>>2,00*22>>2,12*22>>2,12*22>>2,12*22>>2,
  92.    12*22>>2,12*22>>2,00*22>>2,00*22>>2,00*22>>2,00*22>>2,00*22>>2,00*22>>2,01*22>>2,02*22>>2,03*22>>2,04*22>>2,05*22>>2,
  93.    06*22>>2,00*22>>2,01*22>>2,02*22>>2,03*22>>2,04*22>>2,05*22>>2,06*22>>2},
  94.   // 4 FAST STROBE
  95.   // "mamamamamama",
  96.   {12*22>>2,00*22>>2,12*22>>2,00*22>>2,12*22>>2,00*22>>2,12*22>>2,00*22>>2,12*22>>2,00*22>>2,12*22>>2,00*22>>2},
  97.   // 5 GENTLE PULSE 1
  98.   // "jklmnopqrstuvwxyzyxwvutsrqponmlkj",
  99.   {9*22>>2,10*22>>2,11*22>>2,12*22>>2,13*22>>2,14*22>>2,15*22>>2,16*22>>2,17*22>>2,18*22>>2,19*22>>2,20*22>>2,21*22>>2,22*22>>2,
  100.    23*22>>2,24*22>>2,25*22>>2,24*22>>2,23*22>>2,22*22>>2,21*22>>2,20*22>>2,19*22>>2,18*22>>2,17*22>>2,16*22>>2,15*22>>2,14*22>>2,
  101.    13*22>>2,12*22>>2,11*22>>2,10*22>>2,9*22>>2},
  102.   // 6 FLICKER (second variety)
  103.   // "nmonqnmomnmomomno",
  104.   {13*22>>2,12*22>>2,14*22>>2,13*22>>2,16*22>>2,13*22>>2,12*22>>2,14*22>>2,12*22>>2,13*22>>2,12*22>>2,14*22>>2,12*22>>2,14*22>>2,
  105.    12*22>>2,13*22>>2,14*22>>2},
  106.   // 7 CANDLE (second variety)
  107.   // "mmmaaaabcdefgmmmmaaaammmaamm",
  108.   {12*22>>2,12*22>>2,12*22>>2,00*22>>2,00*22>>2,00*22>>2,00*22>>2,01*22>>2,02*22>>2,03*22>>2,04*22>>2,05*22>>2,06*22>>2,12*22>>2,
  109.    12*22>>2,12*22>>2,12*22>>2,00*22>>2,00*22>>2,00*22>>2,00*22>>2,12*22>>2,12*22>>2,12*22>>2,00*22>>2,00*22>>2,12*22>>2,12*22>>2},
  110.   // 8 CANDLE (third variety)
  111.   // "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa",
  112.   {12*22>>2,12*22>>2,12*22>>2,00*22>>2,00*22>>2,00*22>>2,12*22>>2,12*22>>2,12*22>>2,00*22>>2,00*22>>2,00*22>>2,12*22>>2,12*22>>2,
  113.    12*22>>2,00*22>>2,01*22>>2,02*22>>2,03*22>>2,04*22>>2,05*22>>2,00*22>>2,00*22>>2,00*22>>2,00*22>>2,12*22>>2,12*22>>2,12*22>>2,
  114.    12*22>>2,00*22>>2,01*22>>2,02*22>>2,03*22>>2,04*22>>2,05*22>>2,12*22>>2,12*22>>2,12*22>>2,00*22>>2,00*22>>2,00*22>>2,00*22>>2},
  115.   // 9 SLOW STROBE (fourth variety)
  116.   // "aaaaaaaazzzzzzzz",
  117.   {00*22>>2,00*22>>2,00*22>>2,00*22>>2,00*22>>2,00*22>>2,00*22>>2,00*22>>2,25*22>>2,25*22>>2,25*22>>2,25*22>>2,25*22>>2,25*22>>2,
  118.    25*22>>2,25*22>>2},
  119.   // 10 FLUORESCENT FLICKER
  120.   // "mmamammmmammamamaaamammma",
  121.   {12*22>>2,12*22>>2,00*22>>2,12*22>>2,00*22>>2,12*22>>2,12*22>>2,12*22>>2,12*22>>2,00*22>>2,12*22>>2,12*22>>2,00*22>>2,12*22>>2,
  122.    00*22>>2,12*22>>2,00*22>>2,00*22>>2,00*22>>2,12*22>>2,00*22>>2,12*22>>2,12*22>>2,12*22>>2,00*22>>2},
  123.   // 11 SLOW PULSE NOT FADE TO BLACK
  124.   // "abcdefghijklmnopqrrqponmlkjihgfedcba"
  125.   {0*22>>2,1*22>>2,2*22>>2,3*22>>2,4*22>>2,5*22>>2,6*22>>2,7*22>>2,8*22>>2,9*22>>2,10*22>>2,11*22>>2,12*22>>2,13*22>>2,14*22>>2,15*22>>2,
  126.    16*22>>2,17*22>>2,17*22>>2,16*22>>2,15*22>>2,14*22>>2,13*22>>2,12*22>>2,11*22>>2,10*22>>2,9*22>>2,8*22>>2,7*22>>2,6*22>>2,5*22>>2,
  127.    4*22>>2,3*22>>2,2*22>>2,1*22>>2,0*22>>2}
  128. };
  129.  
  130. int lightstyleLengths[11] = {
  131.   1, 23, 51, 33, 12, 17, 28, 42, 16, 25, 36
  132. };
  133.  
  134. void GetTMap(__memBase, struct texture *Text, short int mip)
  135. {
  136.   int i, j, x, y, x0, rows, lines;
  137.   unsigned char *lightmap;
  138.   int *lightindex;
  139.   struct fastmipmap *fastMM;
  140.   unsigned char *data;
  141.  
  142.   fastMM = &Text->mipMaps[mip];
  143.   textureType = Text->textureType;
  144.   /*
  145.    * skies have no lighting infos, and are not mipmapped
  146.    */
  147.   if(Text->textureType == SKY_TYPE) {
  148.     Text->texChanged = FALSE;
  149.     textureRow = Text->mipMaps[MIPMAP_0].rawBody.width;
  150.     texture = Text->mipMaps[MIPMAP_0].rawBody.data;
  151.     return;
  152.   }
  153.   /*
  154.    * non-walls can have lighting info, but no special properties in size
  155.    */
  156.   else if(Text->textureType != WALL_TYPE) {
  157.     rows = fastMM->rawBody.width;
  158.     lines = fastMM->rawBody.height;
  159.     textureMask1 = ((rows - 1) << WARP_SHIFT) >> mip;
  160.     textureMask2 = (rows - 1) >> mip;
  161.     textureShift1 = 16 - WARP_SHIFT + mip;
  162.     textureShift2 = 16 - mip;
  163.  
  164. #ifdef    FAST_WARP
  165.     swim_u = swim_um[mip];
  166.     swim_v = swim_vm[mip];
  167. #endif
  168.     switch(textureType) {
  169.       case WATER_TYPE:    preTransparency = waterTransparency; break;    // 50
  170.       case SLIME_TYPE:    preTransparency = slimeTransparency; break;    // 75
  171.       default:            preTransparency = lavaTransparency;  break;    // 90
  172.     }
  173.   }
  174.   /*
  175.    * walls are the most complex
  176.    */
  177.   else {
  178.     rows = fastMM->newBody.width;
  179.     lines = fastMM->newBody.height;
  180.   }
  181.   textureRow = rows;
  182.   texture = data = Text->tiled;
  183. //UpdateDisplay(texture, 0, 0, rows, lines);
  184.  
  185.   if(Text->texChanged == TRUE) {
  186.     Text->texChanged = FALSE;
  187.     
  188.     step = fastMM->step;
  189.     shift = fastMM->shift;
  190.     row = fastMM->row;
  191.  
  192.     y = fastMM->y;
  193.     x0 = fastMM->x0;
  194.  
  195.     /*
  196.      * this could be if we have no lightinformation, or if the face emits no light
  197.      */
  198.     if(!(lightmap = Text->lightdata)) {
  199.       if((bspMem->dlightdata) && (textureType == WALL_TYPE))
  200.         brightColormap = &cachedColormap[0x0003D00];    /* standard ambient */
  201.       else
  202.         brightColormap = &cachedColormap[0x0001F00];    /* full bright (no lights), for waters etc. and if no lightinfo */
  203.  
  204.       for (j = 0; j < lines; j += step) {
  205.         x = x0;
  206.         for (i = 0; i < rows; i += step) {
  207.           BuildBrightBlock(data + lookup(j, rows) + i, &fastMM->rawBody, x, y);
  208.           x += step;
  209.           if (x >= fastMM->rawBody.width)
  210.         x -= fastMM->rawBody.width;
  211.         }
  212.         y += step;
  213.         if (y >= fastMM->rawBody.height)
  214.           y -= fastMM->rawBody.height;
  215.       }
  216.     }
  217.     else {
  218.       /*
  219.        * so, we need a framecounter, the lights state is "lightstate = lighttable[lightstyle][framecounter % strlen(lighttable[lightstyle])]"
  220.        * lighttable is an array into the lightstyle-strings
  221.        * we have 26 different chars (a - z), a is total darkness and z is maxbright, m (12) is fullbright
  222.        * we need a double calculated as "(lightstate - 'a') / 12.0" (0.0-2.16) or as "(lightstate - 'a') * 21.25"
  223.        * normal brightness is 0x1F, so "0x1F * 0.0 = 0" and "0x1F * 2.16 ~= 0x3F"
  224.        */
  225.       lightmapWidth = Text->lightmap.width;
  226.       lightmapIndex = (int *)Text->lightmap.data;
  227.       memset(lightmapIndex, 0, Text->lightmap.size * sizeof(int));
  228.  
  229.       for(j = 0; (j < MAXLIGHTMAPS); j++) {            // max 4
  230.         int lightState;
  231.         short int *lightStyle;
  232.       
  233.         if(!(lightStyle = Text->lightSString[j]))
  234.           break;
  235.         if(Text->lightSLength[j] > 1)                // dynamic texture changing, next frame must also be processed by this routine
  236.           Text->texChanged = TRUE;                // if the string is only one pattern long, there is no changing from frame to frame
  237.  
  238.         lightState = lightStyle[frameCounter % Text->lightSLength[j]];
  239.         lightindex = lightmapIndex;
  240.       
  241.         for(i = 0; i < Text->lightmap.size; i++)
  242.           *lightindex++ += (*lightmap++ * lightState);        // all the light-styles
  243.       }
  244.  
  245.       lightindex = lightmapIndex;
  246.       for(i = 0; i < Text->lightmap.size; i++) {        // over- and underflow-correction
  247.         int sum = *lightindex + (10 << 6);            // ambient light
  248.       
  249.         if(sum > (255 << 6))                    // 64 = 1<<6 light-values
  250.           sum = (255 << 6);
  251.         else if(sum < (  0 << 6))
  252.           sum = (  0 << 6);
  253.       
  254.         *lightindex++ = sum;
  255.       }
  256.  
  257.       for (j = 0; j < lines; j += step) {
  258.         x = x0;
  259.         for (i = 0; i < rows; i += step, ++lightmapIndex) {
  260.           BuildLightBlock(data + lookup(j, rows) + i, &fastMM->rawBody, x, y);
  261.           x += step;
  262.           if (x >= fastMM->rawBody.width)
  263.         x -= fastMM->rawBody.width;
  264.         }
  265.         ++lightmapIndex;
  266.         y += step;
  267.         if (y >= fastMM->rawBody.height)
  268.           y -= fastMM->rawBody.height;
  269.       }
  270.     }
  271.   }
  272. }
  273.